<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test.js"></script>
</head>
<body>
<p id="description"></p>
<p>
Please run this with DumpRenderTree.
</p>
Test following keys:
<ul>
    <li>Digits</li>
    <li>Left/Right - Move focus field inside element</li>
    <li>Up/Down - Increment/decrement value of focus field</li>
    <li>Tab - Move focus field</li>
    <li>Backspace - Make value empty</li>
</ul>
<input id="before">
<input id="input" type="date">
<input id="after">
<div id="console"></div>
<script>
description('Multiple fields UI of month input type with keyboard events');
if (window.internals)
    internals.runtimeFlags.langAttributeAwareFormControlUIEnabled = true;
var input = document.getElementById('input');

function keyDown(key, modifiers)
{
    if (!window.eventSender)
        return;
    eventSender.keyDown(key, modifiers);
}

function beginTest(opt_title, opt_value, opt_min, opt_max)
{
    if (opt_title)
        debug('== ' + opt_title + ' ==');
    input.value = opt_value || '';
    input.min = opt_min ? opt_min : '';
    input.max = opt_max ? opt_max : '';
    input.blur();
    input.focus();
}

// We assume the date format is MM/dd/yyyy.

beginTest('Digit keys');
keyDown('9'); // -> 09/[dd]/yyyy
keyDown('2'); // -> 09/[02]/yyyy
keyDown('0'); // -> 09/20/[yyyy]
keyDown('1'); // -> 09/20/[0001]
keyDown('2'); // -> 09/20/[0012]
keyDown('A'); // Ignored.
shouldBeEqualToString('input.value', '0012-09-20');

beginTest('Digit keys starting with zero');
keyDown('0'); // -> [00]/dd/yyyy
keyDown('2'); // -> 02/[dd]/yyyy
keyDown('0'); // -> 02/[00]/yyyy
keyDown('3'); // -> 02/03/[yyyy]
keyDown('0'); // -> 02/03/[0000]
keyDown('0'); // -> 02/03/[0000]
keyDown('0'); // -> 02/03/[0000]
keyDown('4'); // -> 02/03/[0004]
keyDown('4'); // -> 02/03/[0044]
shouldBeEqualToString('input.value', '0044-02-03');

beginTest('Digit keys and backspace key');
keyDown('1'); // -> [01]/dd/yyyy
keyDown("Backspace"); // -> [mm]/20/2012
keyDown('5'); // -> 05/[dd]/yyyy
keyDown('6'); // -> 05/06/[yyyy]
keyDown("Backspace"); // -> 05/06/[yyyy]
keyDown('7'); // -> 05/06/[0007]
keyDown("Backspace"); // -> 05/06/[yyyy]
keyDown('8'); // -> 05/06/[0008]
shouldBeEqualToString('input.value', '0008-05-06');

beginTest('Digit keys with maximum value', null, null, '2013-01-01');
keyDown('5'); // -> 05/[dd]/yyyy
keyDown('6'); // -> 05/06/[yyyy]
keyDown('2'); // -> 05/06/[0002]
keyDown('0'); // -> 05/06/[0020]
keyDown('1'); // -> 05/06/[0201]
keyDown('4'); // -> 05/06/[2014] We accept a value larger than the maximum.
shouldBeEqualToString('input.value', '2014-05-06');
keyDown('5'); // -> 05/06/[0145] We don't accept a value of which the number of digits is longer than one of the maximum.
shouldBeEqualToString('input.value', '0145-05-06');

beginTest('Digit keys with minimum value', null, '2013-01-01');
keyDown('5'); // -> 05/[dd]/yyyy
keyDown('6'); // -> 05/06/[yyyy]
keyDown('1'); // -> 05/06/[0001]
keyDown('9'); // -> 05/06/[0019]
keyDown('9'); // -> 05/06/[0199]
keyDown('9'); // -> 05/06/1999
shouldBeEqualToString('input.value', '1999-05-06');

beginTest('Entering "00" to month', '2013-04-16');
keyDown('0'); // -> [00]/16/2013
keyDown('0'); // -> 01/[16]/2013
shouldBeEqualToString('input.value', '2013-01-16');

beginTest('Entering "13" to month', '2013-04-16');
keyDown('1'); // -> [01]/16/2013
keyDown('3'); // -> 12/[16]/2013
shouldBeEqualToString('input.value', '2013-12-16');

beginTest('Left/Right keys', '2012-09-29');
keyDown('ArrowRight'); // -> 09/[29]/2012
keyDown('5'); // -> 09/05/[2012]
keyDown('ArrowLeft'); // -> 09/[05]/2012
keyDown('6'); // -> 09/06/[2012]
shouldBeEqualToString('input.value', '2012-09-06');
keyDown('ArrowLeft'); // -> 09/[06]/2012
keyDown('ArrowLeft'); // -> [09]/06/2012
keyDown('ArrowLeft'); // -> [09]/06/2012
shouldBeEqualToString('document.activeElement.id', 'input');

beginTest('Up/Down keys', '2012-09-29');
keyDown('ArrowUp'); // -> [10]/29/2012
shouldBeEqualToString('input.value', '2012-10-29');
keyDown('ArrowDown'); // -> [09]/29/2012
keyDown('ArrowDown'); // -> [08]/29/2012
shouldBeEqualToString('input.value', '2012-08-29');

beginTest('Up/Down keys on empty value');
keyDown('ArrowDown'); //  -> [12]/dd/yyyy
keyDown('ArrowDown'); //  -> [11]/dd/yyyy
keyDown('ArrowRight'); // -> 11/[dd]/yyyy
keyDown('ArrowUp'); //    -> 11/[01]/yyyy
keyDown('ArrowUp'); //    -> 11/[02]/yyyy
keyDown('ArrowDown'); //  -> 11/[01]/yyyy
keyDown('ArrowRight'); // -> 11/01/[yyyy]
var currentYear = new Date().getFullYear();
keyDown('ArrowUp'); // -> 11/01/[current year]
shouldBe('input.value', 'currentYear + "-11-01"');

beginTest('Up/Down keys on empty value 2');
keyDown('ArrowUp'); //    -> [01]/dd/yyyy
keyDown('ArrowUp'); //    -> [02]/dd/yyyy
keyDown('ArrowRight'); // -> 02/[dd]/yyyy
keyDown('ArrowDown'); //  -> 02/[31]/yyyy
keyDown('ArrowDown'); //  -> 02/[30]/yyyy
keyDown('ArrowDown'); //  -> 02/[29]/yyyy
keyDown('ArrowDown'); //  -> 02/[28]/yyyy
keyDown('ArrowRight'); // -> 02/28/[yyyy]
currentYear = new Date().getFullYear();
keyDown('ArrowDown'); // -> 02/28/[current year]
shouldBe('input.value', 'currentYear + "-02-28"');

beginTest('Tab key', '2012-09-30');
keyDown('\t'); // -> 09/[30]/2012
keyDown('5'); // -> 09/05/[2012]
shouldBeEqualToString('input.value', '2012-09-05');
keyDown('\t', ['shiftKey']); // -> 09/[05]/2012
keyDown('7'); // -> 09/07/[2012]
shouldBeEqualToString('input.value', '2012-09-07');
keyDown('\t'); // -> Focus out.
shouldBeEqualToString('document.activeElement.id', 'after');

beginTest('Shfit+Tab key', '2012-09-30');
after.focus();
keyDown('\t', ['shiftKey']); // -> 09/30/[yyyy]
keyDown('3'); // -> 09/30/[0003]
shouldBeEqualToString('input.value', '0003-09-30');
keyDown('\t', ['shiftKey']); // -> 09/[30]/0003
keyDown('\t', ['shiftKey']); // -> [09]/30/0003
keyDown('\t', ['shiftKey']); // -> Focus out.
shouldBeEqualToString('document.activeElement.id', 'before');

beginTest('Up key on maximum value', '275760-09-13');
keyDown('ArrowUp'); // -> [10]/13/275760
keyDown('\t'); //      -> 10/[13]/275760
keyDown('ArrowUp'); // -> 10/[14]/275760
keyDown('\t'); //      -> 10/14/[275760]
keyDown('ArrowUp'); // -> 10/14/[0001]
shouldBeEqualToString('input.value', '0001-10-14');
beginTest('Up key with a maximum attribute', '1999-12-31', '1000-01-01', '1999-12-31');
keyDown('ArrowUp'); // -> [01]/31/1999
keyDown('\t'); //      -> 01/[31]/1999
keyDown('ArrowUp'); // -> 01/[01]/1999
keyDown('\t'); //      -> 01/01/[1999]
keyDown('ArrowUp'); // -> 01/01/[1000]
shouldBeEqualToString('input.value', '1000-01-01');

beginTest('Down key on minimum value', '0001-01-01', 'bad min', 'wrong max');
keyDown('ArrowDown'); // -> [12]/01/0001
keyDown('\t'); //        -> 12/[01]/0001
keyDown('ArrowDown'); // -> 12/[31]/0001
keyDown('\t'); //        -> 12/31/[0001]
keyDown('ArrowDown'); // -> 12/31/[275760], which is greater than the hard limit.
shouldBeEqualToString('input.value', '');
beginTest('Down key with a minimum attribute', '1000-01-01', '1000-01-01');
keyDown('ArrowDown'); // -> [12]/01/1000
keyDown('\t'); //        -> 12/[01]/1000
keyDown('ArrowDown'); // -> 12/[31]/1000
keyDown('\t'); //        -> 12/31/[1000]
keyDown('ArrowDown'); // -> 12/31/275760, which is greater than the hard limit.
shouldBeEqualToString('input.value', '');

beginTest('Inconsistent min-max attributes', '1999-12-31', '1999-12-31', '1000-01-01');
keyDown('\t'); // -> 12/[31]/1999
keyDown('\t'); // -> 12/31/[1999]
keyDown('ArrowUp'); // -> 12/31/[1000].  1000 is the swapped minimum year.
shouldBeEqualToString('input.value', '1000-12-31');
keyDown('ArrowDown'); // -> 12/31/[1999]
shouldBeEqualToString('input.value', '1999-12-31');

beginTest('Make an invalid date', '2012-02-01');
keyDown('\t'); //        -> 02/[01]/2012
keyDown('ArrowDown'); // -> 02/[31]/2012
shouldBeEqualToString('input.value', ''); // 2012-02-31 is not a valid date.
input.setAttribute('value', '2012-02-01');
beginTest(undefined, '2012-02-01');
keyDown('\t'); //        -> 02/[01]/2012
keyDown('ArrowDown'); // -> 02/[31]/2012
shouldBeEqualToString('input.value', ''); // 2012-02-31 is not a valid date.
input.removeAttribute('value');

beginTest('Backspace key', '2012-09-20');
keyDown("Backspace"); // -> [mm]/20/2012
shouldBeEqualToString('input.value', '');

beginTest('Delete key', '2012-09-30');
keyDown("Delete"); // -> [mm]/30/2012
shouldBeEqualToString('input.value', '');

beginTest('Typeahead', '2012-12-31');
keyDown('ArrowRight'); // -> 12/[31]/2012
keyDown('1'); //          -> 12/[01]/2012
shouldBeEqualToString('input.value', '2012-12-01');
keyDown('ArrowLeft'); //  -> [12]/01/2012
keyDown('ArrowRight'); // -> 12/[01]/2012
keyDown('2'); //          -> 12/[02]/2012
shouldBeEqualToString('input.value', '2012-12-02');

input.setAttribute("lang", "he-il");
beginTest('RTL focus navigation', '2012-09-28');
debug('The tests in this block fail on platforms without the lang-attribute-aware-form-control-UI feature.');
// Both of the logical order and visual order are: dd/MM/yyyy
// Initial state:            [28]/09/2012
keyDown('ArrowUp'); //    -> [29]/09/2012
keyDown('ArrowRight'); // -> [01]/09/2012
keyDown('1'); //          -> [01]/09/2012
shouldBeEqualToString('input.value', '2012-09-01');
keyDown('\t'); //         -> 01/[09]/2012
keyDown('2'); //          -> 01/02/[2012]
shouldBeEqualToString('input.value', '2012-02-01');
keyDown('\t', ['shiftKey']); // -> 01/[02]/2012/
keyDown('3'); //          -> 01/03/[2012]
shouldBeEqualToString('input.value', '2012-03-01');
input.removeAttribute("lang");

beginTest('Disabled/readonly', '2012-10-08');
input.disabled = true;
keyDown('ArrowUp'); // 10/08/2012
shouldBeEqualToString('input.value', '2012-10-08');
input.disabled = false;
input.focus();
keyDown('ArrowUp'); // [11]/08/2012
shouldBeEqualToString('input.value', '2012-11-08');
input.readOnly = true;
keyDown('ArrowUp'); // 11/08/2012
shouldBeEqualToString('input.value', '2012-11-08');
input.readOnly = false;
input.focus();
keyDown('ArrowUp'); // [12]/08/2012
shouldBeEqualToString('input.value', '2012-12-08');

</script>
</body>
</html>
